<script setup lang="ts">
  import { nextTick, Ref, ref, watch } from 'vue';
  import { FormInstance, Message } from '@arco-design/web-vue';
  import { RoleData } from '@/api/role/types';
  import { createRole, editRole, getRoleDetail } from '@/api/role';
  import { getMenuTree } from '@/api/menu';
  import { MenuTree } from '@/api/menu/types';
  import { debounce } from 'lodash';

  const emit = defineEmits(['saveSuccess']);
  const dialogVisiable = ref(false);
  const addForm: Ref<RoleData | any> = ref({
    id: undefined,
    name: '',
    code: '',
    enable: 1,
    checkedPermission: [],
    halfCheckedPermission: [],
  });
  const treeData: Ref<MenuTree[]> = ref([]);
  const formRules: FormInstance['rules'] = {
    name: [{ required: true, message: '角色名不能为空' }],
    code: [{ required: true, message: '编码不能为空' }],
  };
  const formRef = ref();
  const treeRef = ref();
  const saveId = ref();
  const isRules = ref(false);
  const IsChecked = ref(false);
  const onExpanded = ref(false);
  // 使用 watch 监听 dialogVisiable 的值
  watch(
    () => dialogVisiable.value,
    async (newValue) => {
      if (newValue) {
        const result = await getMenuTree(true);
        treeData.value = result.data;
      }
    },
    { immediate: true }, // 确保在组件初始化时也调用一次
  );
  // 获得半选和选中节点的key
  const getCheckedKeys = (arrayNodes: any): number[] => {
    const keys = new Set<number>();
    arrayNodes.forEach((item: any) => {
      if (item.key !== '0') {
        keys.add(item.key);
      }
    });
    return Array.from(keys);
  };
  // 保存
  const handleSave = async () => {
    try {
      const isInvalid = await formRef.value?.validate();
      if (isInvalid) return false;
      // 保存和编辑
      if (saveId.value) {
        addForm.value.checkedPermission = getCheckedKeys(
          treeRef.value?.getCheckedNodes('all'),
        );
        addForm.value.halfCheckedPermission = getCheckedKeys(
          treeRef.value?.getHalfCheckedNodes(),
        );
        delete addForm.value.permission;
        await editRole(addForm.value);
      } else {
        delete addForm.value.id;
        addForm.value.checkedPermission = getCheckedKeys(
          treeRef.value?.getCheckedNodes('all'),
        );
        addForm.value.halfCheckedPermission = getCheckedKeys(
          treeRef.value?.getHalfCheckedNodes(),
        );
        await createRole(addForm.value);
      }
      // 关闭对话框
      dialogVisiable.value = false;
      emit('saveSuccess');
      Message.success('保存成功');
      return true;
    } catch (error) {
      return false;
    }
  };
  const handleOpen = async () => {
    dialogVisiable.value = true;
    nextTick(() => {
      onExpanded.value = false;
      treeRef.value.expandAll(onExpanded.value);
    });
  };
  // 编辑
  const handleEdit = async (id: number) => {
    dialogVisiable.value = true;
    saveId.value = id;
    const result = await getRoleDetail(id);
    addForm.value = result.data;
    addForm.value.checkedPermission = result.data.permission;
    if (addForm.value.checkedPermission.length > 0) {
      nextTick(() => {
        onExpanded.value = true;
        treeRef.value.expandAll(onExpanded.value);
      });
    }
  };
  // 点击关闭-取消按钮后触发
  const handleCancel = () => {
    dialogVisiable.value = false;
  };
  // 对话框关闭后触发
  const handleClose = () => {
    // 自带重置方法失效 手动重置
    addForm.value.name = '';
    addForm.value.code = '';
    addForm.value.enable = 1;
    addForm.value.checkedPermission = [];
    addForm.value.halfCheckedPermission = [];
    saveId.value = undefined;
  };
  // 暴露方法
  defineExpose({
    handleOpen,
    handleEdit,
  });
  // 全选
  const toggleChecked = debounce((value: any) => {
    treeRef.value.checkAll(value);
  }, 200);
  // 展开
  const toggleExpanded = debounce((value: any) => {
    treeRef.value.expandAll(value);
  }, 200);
</script>

<template>
  <a-modal
    :visible="dialogVisiable"
    title-align="start"
    :ok-text="$t('modal.operation.save')"
    :cancel-text="$t('modal.operation.cancel')"
    unmount-on-close
    @before-ok="handleSave"
    @close="handleClose"
    @cancel="handleCancel"
  >
    <template #title
      >{{
        saveId
          ? $t('searchTable.operation.edit')
          : $t('searchTable.operation.create')
      }}
    </template>
    <a-form
      ref="formRef"
      :rules="formRules"
      :model="addForm"
      style="height: 400px; overflow: auto; padding-right: 16px"
      auto-label-width
    >
      <a-form-item field="name" label="角色名">
        <a-input
          v-model="addForm.name"
          allow-clear
          placeholder="请输入角色名"
        ></a-input>
      </a-form-item>
      <a-form-item field="code" label="编码">
        <a-input v-model="addForm.code" placeholder="请输入编码" allow-clear />
      </a-form-item>
      <a-form-item field="permission" label="权限">
        <div class="rule_data">
          <div class="header">
            <a-checkbox
              v-if="!isRules"
              v-model="IsChecked"
              style="margin-right: 16px"
              @change="toggleChecked"
            >
              {{ IsChecked ? '取消' : '全选' }}
            </a-checkbox>
            <a-checkbox v-model="onExpanded" @change="toggleExpanded"
              >{{ onExpanded ? '收起' : '展开' }}
            </a-checkbox>
          </div>
          <div class="treebox">
            <a-tree
              ref="treeRef"
              v-model:checked-keys="addForm.checkedPermission"
              :checkable="true"
              :check-strictly="false"
              :data="treeData"
              show-line
            />
          </div>
        </div>
      </a-form-item>
      <a-form-item field="enable" label="状态">
        <a-switch
          v-model="addForm.enable"
          :checked-value="1"
          :unchecked-value="0"
          checked-text="开启"
          unchecked-text="关闭"
          type="round"
        />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<style scoped lang="less">
  .rule_data {
    width: 100%;

    .header {
      padding-bottom: 4px;
      margin-bottom: 3px;
      border-bottom: var(--color-neutral-4) solid 1px;
    }
  }
</style>
